/*
* This file is a part of the open-eBackup project.
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
* If a copy of the MPL was not distributed with this file, You can obtain one at
* http://mozilla.org/MPL/2.0/.
*
* Copyright (c) [2024] Huawei Technologies Co.,Ltd.
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*/
package openbackup.system.base.sdk.copy.model;

import com.google.common.collect.ImmutableList;

import openbackup.system.base.common.constants.CommonErrorCode;
import openbackup.system.base.common.exception.LegoCheckedException;

import java.util.Arrays;
import java.util.List;

/**
 * 功能描述
 *
 */
public enum CopyGeneratedByEnum {
    /**
     * The copy is generated by backup
     */
    BY_BACKUP("Backup"),

    /**
     * The copy is generated by cloud archive
     */
    BY_CLOUD_ARCHIVE("CloudArchive"),

    /**
     * The copy is generated by tape archive
     */
    BY_TAPE_ARCHIVE("TapeArchive"),

    /**
     * The copy is generated by live mount
     */
    BY_LIVE_MOUNTE("live_mount"),

    /**
     * The copy is generated by replicated
     */
    BY_REPLICATED("Replicated"),

    /**
     * The copy is generated by Imported
     */
    BY_IMPORTED("Imported"),

    /**
     * The copy is generated by common interface backup
     */
    BY_COMMON_INTERFACE_BACKUP("CommonInterfaceBackup"),

    /**
     * dws副本归档到磁带的需要先下载到A8000，再做恢复
     * 其他应用副本，包括dws归档到云的副本不用下载到A8000，直接恢复
     */
    BY_DOWNLOAD("Download"),

    /**
     * 由级联复制生成
     */
    BY_CASCADED_REPLICATION("CascadedReplication"),

    /**
     * 由反向复制生成
     */
    BY_REVERSE_REPLICATION("ReverseReplication");

    /**
     * 恢复是否可以停止
     */
    public static final List<String> RESTORE_CAN_STOP = ImmutableList.of(
            CopyGeneratedByEnum.BY_BACKUP.value(),
            CopyGeneratedByEnum.BY_CLOUD_ARCHIVE.value(),
            CopyGeneratedByEnum.BY_TAPE_ARCHIVE.value(),
            CopyGeneratedByEnum.BY_REPLICATED.value(),
            CopyGeneratedByEnum.BY_LIVE_MOUNTE.value(),
            CopyGeneratedByEnum.BY_IMPORTED.value()
    );

    /**
     * 副本复制生成方式列表
     */
    public static final List<String> COPY_GENERATED_BY_REPLICATION = ImmutableList.of(
            CopyGeneratedByEnum.BY_REPLICATED.value(),
            CopyGeneratedByEnum.BY_CASCADED_REPLICATION.value(),
            CopyGeneratedByEnum.BY_REVERSE_REPLICATION.value()
    );

    /**
     * 副本复制备份和即时挂载生成方式列表
     */
    public static final List<String> COPY_GENERATED_BY_REPLICATION_AND_BACKUP_AND_LIVE_MOUNT = ImmutableList.of(
        CopyGeneratedByEnum.BY_REPLICATED.value(), CopyGeneratedByEnum.BY_CASCADED_REPLICATION.value(),
        CopyGeneratedByEnum.BY_REVERSE_REPLICATION.value(), CopyGeneratedByEnum.BY_BACKUP.value(),
        CopyGeneratedByEnum.BY_LIVE_MOUNTE.value());

    private final String generatedBy;

    CopyGeneratedByEnum(String generatedBy) {
        this.generatedBy = generatedBy;
    }

    /**
     * return the value
     *
     * @return String
     */
    public String value() {
        return generatedBy;
    }

    /**
     * 根据副本生成类型获取副本生成类型的枚举类
     *
     * @param generatedType 副本生成类型
     * @return 副本生成类型的枚举类 {@code CopyGeneratedByEnum}
     */
    public static CopyGeneratedByEnum getByGenerateType(String generatedType) {
        return Arrays.stream(CopyGeneratedByEnum.values())
            .filter(generateType -> generateType.generatedBy.equals(generatedType))
            .findFirst()
            .orElseThrow(() -> new LegoCheckedException(CommonErrorCode.ILLEGAL_PARAM, "copy type illegal!"));
    }

    /**
     * 当前副本生成类型是否支持恢复任务停止
     *
     * @return 是否支持恢复任务停止
     */
    public boolean restoreCanStop() {
        return RESTORE_CAN_STOP.contains(this.value());
    }

    /**
     * 副本生成类型是否支持恢复任务停止
     *
     * @param generatedBy 副本生成类型
     * @return 是否支持恢复任务停止
     */
    public static boolean restoreCanStop(String generatedBy) {
        return RESTORE_CAN_STOP.contains(generatedBy);
    }
}
